/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package agents;

import env.Action;
import env.Enviroment;
import env.Tile;

/**
 * 
 * @author user
 */
public class AgentState {

    private Tile tile;
    private Action lastAction; //what got me here?

    public AgentState(int row, int col, Action lastAction) {
        this.tile = Enviroment.env.getTile(row, col);
        this.lastAction = lastAction;
    }

    private AgentState(Tile tile, Action lastAction) {
        this.tile = tile;
        this.lastAction = lastAction;
    }

    public int getCol() {
        //return col;
        return tile.getCol();
    }

    public int getRow() {
        //return row;
        return tile.getRow();
    }

    public Action getLastAction() {
        return lastAction;
    }
    
    public void updatePosition(Action move) {
        //just moved into ice (and not stopped already):
        if (tile.isIce() && this.lastAction != null) {
            if (tile.getNeighbor(lastAction).isWall()) {
                move = null; //crash
            } else {
                move = lastAction; //slide
            }
        }
        if (move != null) {
            Tile nextTile = tile.getNeighbor(move);
            //just to make sure not attempting to be in wall or outside map:
            if (nextTile != null && !nextTile.isWall()) {
                tile = nextTile;
            }
        }

        lastAction = move;
    }

    public boolean isLegalMove(Action move) {
        final Tile targetTile = getTile().getNeighbor(move);
        if (getTile().isIce() && move != this.lastAction && !getTile().getNeighbor(lastAction).isWall()) {
            return false;
        }
        return targetTile != null && !targetTile.isWall();
    }

    public AgentState clone(Action move) {
        AgentState s = new AgentState(tile, lastAction);// new AgentState(row, col);
        s.updatePosition(move);
        return s;
    }

    public Tile getTile() {
        //return Enviroment.env.getTile(row, col);
        return tile;
    }



    /* TODO: important!!! if you can prove you can use this set of equals and hashcode, the search
     * will be MUCH FASTER!!!!
     * 
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final AgentState other = (AgentState) obj;
        if (this.tile != other.tile) {
            return false;
        }
        if (tile.isIce() && this.lastAction != other.lastAction) { //lastAction only matters on icy tiles?
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = this.tile.hashCode();
        if (tile.isIce()) {
            hash = 41 * hash + (this.lastAction != null ? this.lastAction.hashCode() : 0); //lastAction only matters on icy tiles?
        }
        return hash;
    }

    @Override
    public String toString() {
        //return "state: pos=" + row + "," + col + " last action=" + lastAction;
        return "state: " + tile + " last action=" + lastAction;
    }
}
